#ifndef SERVER_H
#define SERVER_H

#include<QObject>
#include<QHttpServer>
#include<QProtobufSerializer>
#include<QWebSocketServer>
#include<QFileInfo>
#include<QIcon>
#include<QFile>
#include<QPixmap>

//////////////////////////////////////////////////
////// 工具函数
//////////////////////////////////////////////////

//根据路径得到文件名
static inline QString getFileName(const QString& path){
    QFileInfo fileInfo(path);
    return fileInfo.fileName();
}

//封装一个"宏"作为打印日志的方式
#define TAG QString("[%1:%2]").arg(getFileName(__FILE__),QString::number(__LINE__))
//qDebug()打印会自动加上""
#define LOG() qDebug().noquote() << TAG

//要求的函数写在.h需要加上static或者inline,避免链接阶段出现函数“重定义”的问题
static inline QString formatTime(int64_t timestamp){
    //先把时间戳转换成QDateTime对象
    QDateTime dateTime = QDateTime::fromSecsSinceEpoch(timestamp);

    //把QDateTime对象转换成"格式化时间" 月-日 时:分:秒
    return dateTime.toString("MM-dd HH::mm::ss");
}


//通过这个函数得到秒级的时间戳
static inline int64_t getTime(){
    return QDateTime::currentSecsSinceEpoch();
}

//根据QByteArray转成QIcon
static inline QIcon makeIcon(const QByteArray& byteArray){
    QPixmap pixmap;
    pixmap.loadFromData(byteArray);
    QIcon icon(pixmap);
    return icon;
}

//读写操作
//从指定文件中读取一个二进制文件，得到QByteArray
static inline QByteArray loadFiletoByteArray(const QString& path){
    QFile file(path);
    bool ok = file.open(QFile::ReadOnly);
    if(!ok){
        qDebug() << "打开文件失败！";
        return QByteArray();
    }
    QByteArray content = file.readAll();
    file.close();
    return content;
}

//将QByteArray写入到指定文件中
static inline void writeByteArraytoFile(const QByteArray& content , const QString& path){
    QFile file(path);
    bool ok = file.open(QFile::WriteOnly);
    if(!ok){
        qDebug() << "打开文件失败！";
        return ;
    }
    file.write(content);
    file.flush();
    file.close();
}


//////////////////////////////////////////////////
////// HTTP服务器
//////////////////////////////////////////////////

class HttpServer : public QObject{
  Q_OBJECT

private:
    static HttpServer* instance;
    HttpServer();

    QHttpServer httpServer;
    QProtobufSerializer serializer;

public:
    static HttpServer* getInstance();

    //通过这个函数，针对HTTP Server进行初始化(绑定端口，配置路由……)
    bool init();

    //获取用户个人信息
    QHttpServerResponse getUserInfo(const QHttpServerRequest& req);
    //获取用户好友列表
    QHttpServerResponse getFriendList(const QHttpServerRequest& req);
    //获取会话列表
    QHttpServerResponse getChatSessionList(const QHttpServerRequest& req);
    //获取好友申请列表
    QHttpServerResponse getApplyList(const QHttpServerRequest& req);
    //获取指定会话的最近消息列表
    QHttpServerResponse getRecent(const QHttpServerRequest& req);
    //处理发送消息
    QHttpServerResponse newMessage(const QHttpServerRequest& req);
    //修改用户昵称
    QHttpServerResponse setNickname(const QHttpServerRequest& req);
    //修改用户签名
    QHttpServerResponse setDesc(const QHttpServerRequest& req);
    //获取短信验证码
    QHttpServerResponse getPhoneVerifyCode(const QHttpServerRequest& req);
    //修改手机号
    QHttpServerResponse setPhone(const QHttpServerRequest& req);
    //修改头像
    QHttpServerResponse setAvatar(const QHttpServerRequest& req);
    //删除好友
    QHttpServerResponse removeFriend(const QHttpServerRequest& req);
    //添加好友申请
    QHttpServerResponse addFriendApply(const QHttpServerRequest& req);
    //处理好友添加的申请
    QHttpServerResponse addFriendProcess(const QHttpServerRequest& req);
    //创建会话
    QHttpServerResponse createChatSession(const QHttpServerRequest& req);
    //获取成员会话列表
    QHttpServerResponse getChatSessionMember(const QHttpServerRequest& req);
    //推送新的群聊名称
    QHttpServerResponse sendNewGroupName(const QHttpServerRequest& req);
    //搜索用户
    QHttpServerResponse searchFriend(const QHttpServerRequest& req);
    //按关键词搜索历史消息
    QHttpServerResponse searchHistory(const QHttpServerRequest& req);
    //按时间搜索历史消息
    QHttpServerResponse getHistory(const QHttpServerRequest& req);
    //基于用户名密码登录
    QHttpServerResponse usernameLogin(const QHttpServerRequest& req);
    //基于用户名密码注册
    QHttpServerResponse usernameRegister(const QHttpServerRequest& req);
    //基于电话号码登录
    QHttpServerResponse phoneLogin(const QHttpServerRequest& req);
    //基于电话号码注册
    QHttpServerResponse phoneRegister(const QHttpServerRequest& req);
    //获取单个文件
    QHttpServerResponse getSingleFile(const QHttpServerRequest& req);
    //语音转文字
    QHttpServerResponse recognition(const QHttpServerRequest& req);
};

//////////////////////////////////////////////////
////// WebSocket服务器
//////////////////////////////////////////////////

class WebsocketServer : public QObject{
    Q_OBJECT

private:
    static WebsocketServer* instance;
    WebsocketServer():websocketServer("websocket server",QWebSocketServer::NonSecureMode){}

    QWebSocketServer websocketServer;

    QProtobufSerializer serializer;

    int messageIndex = 0;

public:
    static WebsocketServer* getInstance();

    bool init();

signals:
    void sendTextResp();
    void sendImageResp();
    void sendFileResp();
    void sendSpeechResp();
    void sendFriendRemove();
    void sendAddFriendApply();
    void sendAddFriendProcess(bool agree);
    void sendCreateChatSession();
    void sendNewGroupName();
};

#endif // SERVER_H
